import FYBaseNode from "./FYBaseNode";
import FYGridBloodSample from "./FYGridBloodSample";
import FYUtility from "./FYUtility";

const { ccclass, property } = cc._decorator;
/** 
 * 网格 血量
 * 用法：
 *      先调用init方法。扣血的时候调用subBlood方法。
 *      如果最大血量发生变化则调用refreshMaxBlood。
 *      血量会自动恢复，恢复速度看子对象FYGridBloodSample
 */
@ccclass
export default class FYGridBlood extends FYBaseNode {
    /** 容器 */
    @property(cc.Node)
    public container: cc.Node = null;
    /** 血量样品 */
    @property(cc.Node)
    public gridBloodSample: cc.Node = null;
    /** 血量对象列表 */
    private _listBlood: Array<FYGridBloodSample> = [];
    /** 当前血量 */
    private _nCurBlood: number = 0;
    /** 最大血量 */
    private _nMaxBlood: number = 0;
    /** 空血回调 */
    private _cbEmptyBlood = null;

    /**
     * 添加监听
     */
    addListener() {

    }

    /**
     * 移除监听
     */
    removeListener() {

    }

    /**
     * 初始化回调函数
     * @param cbEmptyBlood 空血回调
     */
    public init(curBlood, maxBlood, cbEmptyBlood) {
        this._nCurBlood = curBlood;
        this._nMaxBlood = maxBlood;
        this._cbEmptyBlood = cbEmptyBlood;

        this.refreshMaxBlood(this._nMaxBlood);
    }

    /** 重置血量 */
    public resetBlood() {
        this._nCurBlood = this._nMaxBlood;
        this.refreshMaxBlood(this._nMaxBlood);
    }

    /**
     * 刷新最大血量
     * @param maxBlood 最大血量
     */
    public refreshMaxBlood(maxBlood: number) {
        this.refreshListRoleBlood();
        let num = maxBlood - this._listBlood.length;
        let deltaBlood = this._nMaxBlood - this._nCurBlood;
        this._nMaxBlood = maxBlood;
        this._nCurBlood = this._nMaxBlood - (deltaBlood > 0 ? deltaBlood : 0);
        if (num > 0) {
            for (let i = 0; i < num; i++) {
                let node = FYUtility.addChild(this.container, this.gridBloodSample, cc.Vec2.ZERO, true);
                node.setSiblingIndex(1);
            }
            this.initBlood();
        } else if (num < 0) {
            for (let i = -num; i > 0 && this._listBlood.length > 0; i--) {
                this._listBlood[this._listBlood.length - 1].node.destroy();
                this._listBlood.pop();
            }
        }
    }

    /** 
     * 扣血
     * return : 是否死亡
     */
    public subBlood(): boolean {
        if (this._nCurBlood > 0) {
            this._nCurBlood--;
            if (this._nCurBlood === 0) {
                if (this._cbEmptyBlood) {
                    this._cbEmptyBlood();
                    return true;
                }
            } else {
                if (this._nCurBlood === this._listBlood.length - 1) {
                    // 如果是扣除的第一滴血，则直接扣除
                    this._listBlood[this._nCurBlood].subBlood();
                } else {
                    // 如果不是扣除的第一滴血，则回血逻辑需要前移
                    let radio = this._listBlood[this._nCurBlood + 1].getBloodRestoreRadio();
                    this._listBlood[this._nCurBlood].setBloodRestoreRadio(radio);
                    this._listBlood[this._nCurBlood].startRestoreBlood();
                    this._listBlood[this._nCurBlood + 1].setBloodRestoreRadio(0);
                }

            }
            return false;
        } else {
            if (this._cbEmptyBlood) {
                this._cbEmptyBlood();
            }
            return true;
        }
    }

    /** 获取当前血量 */
    public getCurBlood() {
        return this._nCurBlood;
    }


    /** 初始化血量 */
    private initBlood() {
        this.refreshListRoleBlood();
        for (let i = 0; i < this._listBlood.length; i++) {
            this._listBlood[i].init(this.onRestoreBlood.bind(this));
        }
    }

    /** 刷新角色血量列表 */
    private refreshListRoleBlood() {
        this._listBlood = this.container.getComponentsInChildren(FYGridBloodSample);
    }


    /* ------------------- 回调 ---------------------- */

    /** 血量恢复回调 */
    onRestoreBlood() {
        this._nCurBlood++;
        if (this._nCurBlood > this._nMaxBlood) {
            this._nCurBlood = this._nMaxBlood;
        }
        // 如果还有没有恢复的血量，则继续恢复
        if (this._nCurBlood < this._listBlood.length) {
            this._listBlood[this._nCurBlood].startRestoreBlood();
        }
    }

    /* -------------------生命周期--------------------- */
}
